package service.impl;

import entity.*;
import dao.ClassDao;
import dao.impl.ClassDaoImpl;
import dto.GetSameGradeClassDTO;
import service.*;
import util.UUIDUtil;
import vo.GetClassInfoVO;
import vo.GetSameGradeClassVO;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class ClassServiceImpl implements ClassService {
    private final ClassDao classDao = new ClassDaoImpl();
    private final AcademyService academyService = new AcademyServiceImpl();
    private final SpecialtyService specialtyService = new SpecialtyServiceImpl();
    private final TeacherService teacherService = new TeacherServiceImpl();

    @Override
    public List<GetClassInfoVO> getClassInfo(String name) {
        List<Map<String, Object>> mapList = classDao.getClassInfo(name);
        List<ClassEntity> classEntityList = ClassEntity.mapListToEntityList(mapList);
        return getGetClassInfoVOS(classEntityList);
    }

    @Override
    public int addClassInfo(ClassEntity classEntity) {
        classEntity.setId(UUIDUtil.getUUID());
        return classDao.addClassInfo(classEntity);
    }

    @Override
    public int updateClassInfo(ClassEntity classEntity) {
        return classDao.updateClassInfo(classEntity);
    }

    @Override
    public int deleteClass(String classId) {
        return classDao.deleteClass(classId);
    }

    @Override
    public int batchDeleteClass(List<String> ids) {
        return classDao.batchDeleteClass(ids);
    }

    @Override
    public List<GetClassInfoVO> getClassInfoBySpecialtyId(String specialtyId, String grade) {
        List<ClassEntity> classEntityList = ClassEntity.mapListToEntityList(classDao.getClassInfoBySpecialtyId(specialtyId, grade));
        return getGetClassInfoVOS(classEntityList);
    }

    @Override
    public ClassEntity getClassInfoById(String classId) {
        return ClassEntity.mapToEntity(classDao.getClassInfoById(classId));
    }

    private List<GetClassInfoVO> getGetClassInfoVOS(List<ClassEntity> classEntityList) {
        return classEntityList.stream().map(classEntity -> {
            GetClassInfoVO vo = new GetClassInfoVO();
            SpecialtyEntity specialtyEntity = specialtyService.getSpecialtyInfoById(classEntity.getSpecialtyId());
            if (specialtyEntity != null) {
                vo.setSpecialtyName(specialtyEntity.getSpecialtyName());
                AcademyEntity academyEntity = academyService.getAcademyInfoById(specialtyEntity.getAcademyId());
                if (academyEntity != null) {
                    vo.setAcademyName(academyEntity.getAcademyName());
                } else {
                    vo.setAcademyName("未知学院");
                }
            } else {
                vo.setSpecialtyName("未知专业");
                vo.setAcademyName("未知学院");
            }
            List<StudentEntity> studentEntityList = getClassStudentInfo(classEntity.getId());
            TeacherEntity teacher = teacherService.getTeacherInfoById(classEntity.getTeacherId());
            vo.setTeacherName(teacher.getTeacherName());
            vo.setClassId(classEntity.getId());
            vo.setClassName(classEntity.getClassName());
            vo.setClassCode(classEntity.getClassCode());
            vo.setStudentNum(studentEntityList.size());
            vo.setGrade(classEntity.getGrade());
            return vo;
        }).collect(Collectors.toList());
    }

    @Override
    public List<StudentEntity> getClassStudentInfo(String classId) {
        return StudentEntity.mapListToEntityList(classDao.getClassStudentInfo(classId));
    }

    @Override
    public int removeClassStudent(String studentId) {
        return classDao.removeClassStudent(studentId);
    }

    @Override
    public List<GetSameGradeClassVO> getSameGradeClass(GetSameGradeClassDTO dto) {
        List<Map<String, Object>> mapList = classDao.getSameGradeClass(dto);
        return mapList.stream().map(map -> {
            GetSameGradeClassVO vo = new GetSameGradeClassVO();
            vo.setClassId((String) map.get("id"));
            vo.setClassName((String) map.get("class_name"));
            return vo;
        }).collect(Collectors.toList());
    }
}
